package commRedisStatus

import (
	"encoding/json"
	"gitee.com/fierce_wolf/go-fox-edge-common/commRedis"
	"gitee.com/fierce_wolf/go-fox-edge-common/commUtil/Map"
	"strconv"
	"sync"
	"time"
)

type redisStatusProducerService struct {
	mutex      sync.RWMutex // 读写锁
	updateTime int64
	values     map[string]interface{} // redis缓存
}

func (e *redisStatusProducerService) setUpdateTime(lastTime int64) {
	e.mutex.Lock()
	defer e.mutex.Unlock()

	e.updateTime = lastTime
}

func (e *redisStatusProducerService) getUpdateTime() int64 {
	e.mutex.Lock()
	defer e.mutex.Unlock()

	return e.updateTime
}

func (e *redisStatusProducerService) setValues(values map[string]interface{}) {
	e.mutex.Lock()
	defer e.mutex.Unlock()

	e.values = values
}

func (e *redisStatusProducerService) SetValue(key string, value interface{}) {
	e.mutex.Lock()
	defer e.mutex.Unlock()

	e.values[key] = value
}

func (e *redisStatusProducerService) GetValue(key string) interface{} {
	e.mutex.Lock()
	defer e.mutex.Unlock()

	return e.values[key]
}

func (e *redisStatusProducerService) append(values map[string]interface{}) {
	e.mutex.Lock()
	defer e.mutex.Unlock()

	Map.Append(e.values, values)
}

func (e *redisStatusProducerService) buildJson(serviceKey string) (string, error) {
	e.mutex.Lock()
	defer e.mutex.Unlock()

	if e.values == nil {
		e.values = make(map[string]interface{})
	}

	code, err := json.Marshal(e.values)
	if err != nil {
		return "", err
	}
	jsn := string(code)

	return jsn, nil
}

func (e *redisStatusProducerService) Save() error {
	serviceKey := getServiceKey()

	e.setUpdateTime(time.Now().UnixMilli())

	commRedis.Client.HSet(keySync, serviceKey, e.updateTime)

	jsn, err := e.buildJson(serviceKey)
	if err != nil {
		return err
	}

	_, err = commRedis.Client.HSet(keyData, serviceKey, jsn).Result()
	if err != nil {
		return err
	}

	return nil
}

func (e *redisStatusProducerService) Load() error {
	serviceKey := getServiceKey()

	// 读取redis的时间戳
	strTime, err := commRedis.Client.HGet(keySync, serviceKey).Result()
	i64, err := strconv.ParseInt(strTime, 10, 64)
	if err != nil {
		return err
	}

	// 检查：时间戳是否变化
	if i64 == e.getUpdateTime() {
		return nil
	}

	jsn, err := commRedis.Client.HGet(keyData, serviceKey).Result()
	if err != nil {
		return err
	}

	values := make(map[string]interface{})
	err = json.Unmarshal([]byte(jsn), &values)
	if err != nil {
		return err
	}

	e.setValues(values)
	e.setUpdateTime(i64)
	return nil
}
